package com.government.util;

import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import com.government.common.config.GovernmentConfig;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

@Slf4j
public class Documents4jUtil {

    /**
     * word转pdf
     */
    public static void convertWordToPdf(InputStream stream, String fileName) {
        String os = System.getProperty("os.name").toLowerCase();
        log.info("convertWordToPdf 当前操作系统：{}", os);
        if (os.contains("win")) {
            // Windows操作系统
            windowsWordToPdf(stream, fileName);
        } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
            // Unix/Linux/Mac操作系统
            linuxWordToPdf(stream, fileName);
        } else {
            // 未知操作系统
            throw new RuntimeException("不支持当前操作系统转换文档。");
        }
    }

    /**
     * 通过documents4j 实现word转pdf -- Windows 环境 需要有 Microsoft Office 服务
     */
//    public static void windowsWordToPdf(InputStream stream, String fileName) {
//        try {
//            IConverter converter = LocalConverter.builder().build();
//
//            // 转换后pdf生成地址
////            String downloadPath = GovernmentConfig.getDownloadPath() + fileName;
//            String downloadPath = "D://" + fileName.substring(0, fileName.indexOf(".")) + ".pdf";
//            OutputStream outputStream = new FileOutputStream(downloadPath);
//            converter.convert(stream)
//                    .as(DocumentType.DOCX)
//                    .to(outputStream)
//                    .as(DocumentType.PDF).execute();
//        } catch (Exception e) {
//            log.error("winWordToPdf windows环境word转换为pdf时出现异常：", e);
//        }
//    }
    public static void windowsWordToPdf(InputStream stream, String fileName) {
        try {
            // 统一保存到可被静态资源映射访问的目录：{profile}/upload/convert/{name}.pdf
            String baseDir = GovernmentConfig.getUploadPath() + "/convert/";
            File dir = new File(baseDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }

            String baseName = fileName.contains(".") ? fileName.substring(0, fileName.lastIndexOf('.')) : fileName;
            String downloadPath = baseDir + baseName + ".pdf";

            // 根据扩展名选择正确的文档类型，默认按DOCX处理
            String ext = fileName.contains(".") ? fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase() : "docx";
            DocumentType inputType = "doc".equals(ext) ? DocumentType.DOC : DocumentType.DOCX;

            IConverter converter = LocalConverter.builder().build();
            try (OutputStream outputStream = new FileOutputStream(downloadPath)) {
                converter.convert(stream)
                        .as(inputType)
                        .to(outputStream)
                        .as(DocumentType.PDF).execute();
            }
        } catch (Exception e) {
            log.error("winWordToPdf windows环境word转换为pdf时出现异常：", e);
        }
    }

    /**
     * 通过libreoffice 实现word转pdf -- linux 环境 需要有 libreoffice 服务
     */
    public static void linuxWordToPdf(InputStream stream, String fileName) {
        // 创建临时文件
        File tempFile = createTempFileFromInputStream(stream);
        // 构建LibreOffice的命令行工具命令
        String command = "libreoffice24.2 --headless --invisible --convert-to pdf " + tempFile.getAbsolutePath() + " --outdir " + tempFile.getParent();
        // 执行转换命令
        try {
            if (!executeLinuxCmd(command)) {
                throw new IOException("转换失败");
            }
            readPdfFileToByteArrayOutputStream(tempFile, fileName);
        } catch (Exception e) {
            log.error("ConvertWordToPdf: Linux环境word转换为pdf时出现异常：" + e + tempFile.getPath());
            // 清理临时文件
            tempFile.delete();
        } finally {
            File pdfFile = new File(tempFile.getParent(), tempFile.getName().replace(".docx", ".pdf"));
            //清理转换后的pdf文件
            pdfFile.delete();
            // 清理临时文件，无论是否成功转换
            tempFile.delete();
        }
    }

    /**
     * 执行命令行
     *
     * @param cmd 命令行
     * @return
     * @throws IOException
     */
    private static boolean executeLinuxCmd(String cmd) throws IOException {
        Process process = Runtime.getRuntime().exec(cmd);
        try {
            process.waitFor();
        } catch (InterruptedException e) {
            log.error("executeLinuxCmd 执行Linux命令异常：", e);
            Thread.currentThread().interrupt();
            return false;
        }
        return true;
    }

    /**
     * 创建临时文件
     */
    private static File createTempFileFromInputStream(InputStream inputStream) {
        try {
            File tempFile = File.createTempFile("temp_word", ".docx");
            Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            return tempFile;
        } catch (IOException e) {
            log.error("创建临时文件失败：", e);
            throw new RuntimeException("创建临时文件失败", e);
        }
    }

    /**
     * 读取pdf文件
     */
    private static void readPdfFileToByteArrayOutputStream(File tempFile, String fileName) {
        try {
            // 转换后pdf生成地址
            String downloadPath = GovernmentConfig.getUploadPath()+"/convert/" + fileName.substring(0, fileName.indexOf(".")) + ".pdf";
            OutputStream outputStream = new FileOutputStream(downloadPath);
            Path outputFile = Paths.get(tempFile.getParent(), tempFile.getName().replace(".docx", ".pdf"));
            Files.copy(outputFile, outputStream);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
